//------------------------------------------------------------------------------
// The contents of this file are subject to the nopCommerce Public License Version 1.0 ("License"); you may not use this file except in compliance with the License.
// You may obtain a copy of the License at  http://www.nopCommerce.com/License.aspx. 
// 
// Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. 
// See the License for the specific language governing rights and limitations under the License.
// 
// The Original Code is nopCommerce.
// The Initial Developer of the Original Code is NopSolutions.
// All Rights Reserved.
// 
// Contributor(s): _______. 
//------------------------------------------------------------------------------

using System;
using System.Collections.Generic;
using System.Globalization;
using System.Threading;
using System.Web;
using NopSolutions.NopCommerce.BusinessLogic.Categories;
using NopSolutions.NopCommerce.BusinessLogic.Configuration;
using NopSolutions.NopCommerce.BusinessLogic.Configuration.Settings;
using NopSolutions.NopCommerce.BusinessLogic.CustomerManagement;
using NopSolutions.NopCommerce.BusinessLogic.Directory;
using NopSolutions.NopCommerce.BusinessLogic.Localization;
using NopSolutions.NopCommerce.BusinessLogic.Manufacturers;
using NopSolutions.NopCommerce.BusinessLogic.Orders;
using NopSolutions.NopCommerce.BusinessLogic.Products;
using NopSolutions.NopCommerce.BusinessLogic.Products.Specs;
using NopSolutions.NopCommerce.BusinessLogic.Tax;
using NopSolutions.NopCommerce.BusinessLogic.Utils;
using NopSolutions.NopCommerce.Common;
using NopSolutions.NopCommerce.Common.Utils;

namespace NopSolutions.NopCommerce.BusinessLogic
{
    /// <summary>
    /// Represents a EventContext
    /// </summary>
    public partial class EventContext
    {
        #region Nested
        /// <summary>
        /// Customer event handler
        /// </summary>
        /// <param name="sender">Sender</param>
        /// <param name="e">Arguments</param>
        public delegate void CustomerEventHandler(object sender, CustomerEventArgs e);

        /// <summary>
        /// Order event handler
        /// </summary>
        /// <param name="sender">Sender</param>
        /// <param name="e">Arguments</param>
        public delegate void OrderEventHandler(object sender, OrderEventArgs e);

        /// <summary>
        /// Product event handler
        /// </summary>
        /// <param name="sender">Sender</param>
        /// <param name="e">Arguments</param>
        public delegate void ProductEventHandler(object sender, ProductEventArgs e);

        /// <summary>
        /// Product variant event handler
        /// </summary>
        /// <param name="sender">Sender</param>
        /// <param name="e">Arguments</param>
        public delegate void ProductVariantEventHandler(object sender, ProductVariantEventArgs e);

        //Added by Fast Nop

        /// <summary>
        /// Generic Event handler
        /// </summary>
        /// <param name="sender">Sender</param>
        /// <param name="e">Arguments</param>
        public delegate void NopEventHandler<T>(object sender, NopEventArgs<T> e) where T : BaseEntity;

        /// <summary>
        /// Generic Delete Event handler
        /// </summary>
        /// <param name="sender">Sender</param>
        /// <param name="e">Arguments</param>
        public delegate void NopDeletedEventHandler(object sender, int id);
        

        #endregion

        #region Ctor

        /// <summary>
        /// Creates a new instance of the EventContext class
        /// </summary>
        private EventContext()
        {

        }

        #endregion

        #region Methods

        /// <summary>
        /// Raise customer created event
        /// </summary>
        /// <param name="source">Source</param>
        /// <param name="e">Arguments</param>
        public virtual void OnCustomerCreated(object source, CustomerEventArgs e)
        {
            if (this.CustomerCreated != null)
                this.CustomerCreated(source, e);
        }
        /// <summary>
        /// Raise customer updated event
        /// </summary>
        /// <param name="source">Source</param>
        /// <param name="e">Arguments</param>
        public virtual void OnCustomerUpdated(object source, CustomerEventArgs e)
        {
            if (this.CustomerUpdated != null)
                this.CustomerUpdated(source, e);
        }

        /// <summary>
        /// Raise order created event
        /// </summary>
        /// <param name="source">Source</param>
        /// <param name="e">Arguments</param>
        public virtual void OnOrderCreated(object source, OrderEventArgs e)
        {
            if (this.OrderCreated != null)
                this.OrderCreated(source, e);
        }
        /// <summary>
        /// Raise order placed event
        /// </summary>
        /// <param name="source">Source</param>
        /// <param name="e">Arguments</param>
        public virtual void OnOrderPlaced(object source, OrderEventArgs e)
        {
            if (this.OrderPlaced != null)
                this.OrderPlaced(source, e);
        }
        /// <summary>
        /// Raise order updated event
        /// </summary>
        /// <param name="source">Source</param>
        /// <param name="e">Arguments</param>
        public virtual void OnOrderUpdated(object source, OrderEventArgs e)
        {
            if (this.OrderUpdated != null)
                this.OrderUpdated(source, e);
        }

        /// <summary>
        /// Raise product created event
        /// </summary>
        /// <param name="source">Source</param>
        /// <param name="e">Arguments</param>
        public virtual void OnProductCreated(object source, ProductEventArgs e)
        {
            if (this.ProductCreated != null)
                this.ProductCreated(source, e);
        }
        /// <summary>
        /// Raise product updated event
        /// </summary>
        /// <param name="source">Source</param>
        /// <param name="e">Arguments</param>
        public virtual void OnProductUpdated(object source, ProductEventArgs e)
        {
            if (this.ProductUpdated != null)
                this.ProductUpdated(source, e);
        }

        /// <summary>
        /// Raise product variant created event
        /// </summary>
        /// <param name="source">Source</param>
        /// <param name="e">Arguments</param>
        public virtual void OnProductVariantCreated(object source, ProductVariantEventArgs e)
        {
            if (this.ProductVariantCreated != null)
                this.ProductVariantCreated(source, e);
        }
        /// <summary>
        /// Raise product variant updated event
        /// </summary>
        /// <param name="source">Source</param>
        /// <param name="e">Arguments</param>
        public virtual void OnProductVariantUpdated(object source, ProductVariantEventArgs e)
        {
            if (this.ProductVariantUpdated != null)
                this.ProductVariantUpdated(source, e);
        }

        #region Fast Nop Methods

        //Added by Fast Nop

        public virtual void OnProductCategoryCreated(object source, NopEventArgs<ProductCategory> e)
        {
            if (this.ProductCategoryCreated != null)
                this.ProductCategoryCreated(source, e);
        }

        public virtual void OnProductCategoryUpdated(object source, NopEventArgs<ProductCategory> e)
        {
            if (this.ProductCategoryUpdated != null)
                this.ProductCategoryUpdated(source, e);
        }

        public virtual void OnProductCategoryDeleted(object source, int productId, int categoryId)
        {
            if (this.ProductCategoryDeleted != null)
                this.ProductCategoryDeleted(source, productId, categoryId);
        }

        public virtual void OnProductManufacturerCreated(object source, NopEventArgs<ProductManufacturer> e)
        {
            if (this.ProductManufacturerCreated != null)
                this.ProductManufacturerCreated(source, e);
        }

        public virtual void OnProductManufacturerUpdated(object source, NopEventArgs<ProductManufacturer> e)
        {
            if (this.ProductManufacturerUpdated != null)
                this.ProductManufacturerUpdated(source, e);
        }

        public virtual void OnProductManufacturerDeleted(object source, int productId, int manufacturerId)
        {
            if (this.ProductManufacturerDeleted != null)
                this.ProductManufacturerDeleted(source, productId, manufacturerId);
        }

        public virtual void OnProductSpecificationAttributeCreated(object source, NopEventArgs<ProductSpecificationAttribute> e)
        {
            if (this.ProductSpecificationAttributeCreated != null)
                this.ProductSpecificationAttributeCreated(source, e);
        }

        public virtual void OnProductSpecificationAttributeUpdated(object source, NopEventArgs<ProductSpecificationAttribute> e)
        {
            if (this.ProductSpecificationAttributeUpdated != null)
                this.ProductSpecificationAttributeUpdated(source, e);
        }

        public virtual void OnProductSpecificationAttributeDeleted(object source, int productId, int specificationAttributeOptionId)
        {
            if (this.ProductSpecificationAttributeDeleted != null)
                this.ProductSpecificationAttributeDeleted(source, productId, specificationAttributeOptionId);
        }

        public virtual void OnSpecificationAttributeCreated(object source, NopEventArgs<SpecificationAttribute> e)
        {
            if (this.SpecificationAttributeCreated != null)
                this.SpecificationAttributeCreated(source, e);
        }

        public virtual void OnSpecificationAttributeUpdated(object source, NopEventArgs<SpecificationAttribute> e)
        {
            if (this.SpecificationAttributeUpdated != null)
                this.SpecificationAttributeUpdated(source, e);
        }

        public virtual void OnSpecificationAttributeDeleted(object source, int e)
        {
            if (this.SpecificationAttributeDeleted != null)
                this.SpecificationAttributeDeleted(source, e);
        }

        public virtual void OnSpecificationAttributeOptionCreated(object source, NopEventArgs<SpecificationAttributeOption> e)
        {
            if (this.SpecificationAttributeOptionCreated != null)
                this.SpecificationAttributeOptionCreated(source, e);
        }

        public virtual void OnSpecificationAttributeOptionUpdated(object source, NopEventArgs<SpecificationAttributeOption> e)
        {
            if (this.SpecificationAttributeOptionUpdated != null)
                this.SpecificationAttributeOptionUpdated(source, e);
        }

        public virtual void OnSpecificationAttributeOptionDeleted(object source, int specificationId, int specificationOptionId)
        {
            if (this.SpecificationAttributeOptionDeleted != null)
                this.SpecificationAttributeOptionDeleted(source, specificationId, specificationOptionId);
        }
        #endregion

        #endregion

        #region Properties

        /// <summary>
        /// Gets an instance of the EventContext, which can be used to retrieve information about current context.
        /// </summary>
        public static EventContext Current
        {
            get
            {
                if (HttpContext.Current == null)
                {
                    object data = Thread.GetData(Thread.GetNamedDataSlot("NopEventContext"));
                    if (data != null)
                    {
                        return (EventContext)data;
                    }
                    EventContext context = new EventContext();
                    Thread.SetData(Thread.GetNamedDataSlot("NopEventContext"), context);
                    return context;
                }
                if (HttpContext.Current.Items["NopEventContext"] == null)
                {
                    EventContext context = new EventContext();
                    HttpContext.Current.Items.Add("NopEventContext", context);
                    return context;
                }
                return (EventContext)HttpContext.Current.Items["NopEventContext"];
            }
        }

        /// <summary>
        /// Customer created event
        /// </summary>
        public event CustomerEventHandler CustomerCreated;
        /// <summary>
        /// Customer updated event
        /// </summary>
        public event CustomerEventHandler CustomerUpdated;

        /// <summary>
        /// Order created event
        /// </summary>
        public event OrderEventHandler OrderCreated;
        /// <summary>
        /// Order placed event
        /// </summary>
        public event OrderEventHandler OrderPlaced;
        /// <summary>
        /// Order updated event
        /// </summary>
        public event OrderEventHandler OrderUpdated;

        /// <summary>
        /// Product created event
        /// </summary>
        public event ProductEventHandler ProductCreated;
        /// <summary>
        /// Product updated event
        /// </summary>
        public event ProductEventHandler ProductUpdated;

        /// <summary>
        /// Product variant created event
        /// </summary>
        public event ProductVariantEventHandler ProductVariantCreated;
        /// <summary>
        /// Product variant updated event
        /// </summary>
        public event ProductVariantEventHandler ProductVariantUpdated;

        //Fast Nop events

        //** Product Categories **//
        /// <summary>
        /// Product Category Created
        /// </summary>
        public event NopEventHandler<ProductCategory> ProductCategoryCreated;
        /// <summary>
        /// Product Category Updated
        /// </summary>
        public event NopEventHandler<ProductCategory> ProductCategoryUpdated;
        /// <summary>
        /// Product Category Deleted
        /// </summary>
        public event ProductCategoryDeletedEventHandler ProductCategoryDeleted;
        /// <summary>
        /// Product Category Deleted Event Handler
        /// </summary>
        public delegate void ProductCategoryDeletedEventHandler(object sender, int productId, int categoryId);

        //** Product Manufacturerers **//
        /// <summary>
        /// Product Manufacturer Created
        /// </summary>
        public event NopEventHandler<ProductManufacturer> ProductManufacturerCreated;
        /// <summary>
        /// Product Manufacturer Updated
        /// </summary>
        public event NopEventHandler<ProductManufacturer> ProductManufacturerUpdated;
        /// <summary>
        /// Product Manufacturer Deleted
        /// </summary>
        public event ProductManufacturerDeletedEventHandler ProductManufacturerDeleted;
        /// <summary>
        /// Product Manufacturer Event Handler
        /// </summary>
        public delegate void ProductManufacturerDeletedEventHandler(object sender, int productId, int manufacturerId);

        //** Product Specifications **//
        /// <summary>
        /// Product Specification Attribute Created 
        /// </summary>
        public event NopEventHandler<ProductSpecificationAttribute> ProductSpecificationAttributeCreated;
        /// <summary>
        /// Product Specification Attribute Updated
        /// </summary>
        public event NopEventHandler<ProductSpecificationAttribute> ProductSpecificationAttributeUpdated;
        /// <summary>
        /// Product Specification Attribute Deleted
        /// </summary>
        public event ProductSpecificationAttributeDeletedEventHandler ProductSpecificationAttributeDeleted;
        /// <summary>
        /// Product Specification Attribute Event Handler
        /// </summary>
        public delegate void ProductSpecificationAttributeDeletedEventHandler(object sender, int productId, int specificationAttributeOptionId);

        //** Specifications **//
        /// <summary>
        /// Specification Attribute Created
        /// </summary>
        public event NopEventHandler<SpecificationAttribute> SpecificationAttributeCreated;
        /// <summary>
        /// Specification Attribute Updated
        /// </summary>
        public event NopEventHandler<SpecificationAttribute> SpecificationAttributeUpdated;
        /// <summary>
        /// Specification Attribute Deleted
        /// </summary>
        public event NopDeletedEventHandler SpecificationAttributeDeleted;

        //**Specification Attribute Options **//
        /// <summary>
        /// Specification Attribute Option Created
        /// </summary>
        public event NopEventHandler<SpecificationAttributeOption> SpecificationAttributeOptionCreated;
        /// <summary>
        /// Specification Attribute Option Updated
        /// </summary>
        public event NopEventHandler<SpecificationAttributeOption> SpecificationAttributeOptionUpdated;
        /// <summary>
        /// Specification Attribute Option Deleted
        /// </summary>
        public event SpecificationAttributeOptionDeletedEventHandler SpecificationAttributeOptionDeleted;
        /// <summary>
        /// Specification Attribute Option Event Handler
        /// </summary>
        public delegate void SpecificationAttributeOptionDeletedEventHandler(object sender, int specificationId, int specificationAttributeOptionId);

        #endregion
    }
}
